package com.ymk.cmd;

import com.alibaba.fastjson.JSON;
import com.ymk.base.cmd.ACmd;
import com.ymk.base.cmd.CmdSign;
import com.ymk.base.exception.MallException;
import com.ymk.base.utlis.ParamsBuilder;
import com.ymk.bo.mch.MchBO;
import com.ymk.bo.orders.OrdersBO;
import com.ymk.bo.pay.PayDivideBO;
import com.ymk.bo.pay.PayPaymentBO;
import com.ymk.core.code.cmd.OrdersCmdCode;
import com.ymk.core.code.cmd.PayPaymentCmdCode;
import com.ymk.core.code.req.ReqCode;
import com.ymk.core.constants.SysConstants;
import com.ymk.core.enums.orders.OrdersStatusEnum;
import com.ymk.core.enums.pay.PayDivideStatusEnum;
import com.ymk.core.enums.pay.PayDivideTypeEnum;
import com.ymk.core.enums.pay.PayStatusEnum;
import com.ymk.core.enums.pay.PayTypeEnum;
import com.ymk.mq.MessageSender;
import com.ymk.service.IPayDivideService;
import com.ymk.service.IPayPaymentService;
import com.ymk.service.WxService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Objects;


@Service
public class PayPaymentSyncCmd extends ACmd {
    private final static Logger logger = LoggerFactory.getLogger(PayPaymentSyncCmd.class);

    @Override
    public CmdSign execute(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        PayPaymentBO payPaymentBO = super.getData(sign, PayPaymentBO.class);

        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("id", payPaymentBO.getId());
        PayPaymentBO dbPayPaymentBO = this.payPaymentService.get(paramsBuilder.build());

        // 检验是否已经支付
        if (PayStatusEnum.ACCOUNT_PAID.getStatus().equals(dbPayPaymentBO.getStatus()) ||
                PayStatusEnum.SUCCESS.getStatus().equals(dbPayPaymentBO.getStatus()) ||
                PayStatusEnum.CLOSE.getStatus().equals(dbPayPaymentBO.getStatus())) {
            return respSign;
        }

        PayPaymentBO editPayPaymentBO = new PayPaymentBO();
        editPayPaymentBO.setPayNo(dbPayPaymentBO.getPayNo());
        editPayPaymentBO.setId(dbPayPaymentBO.getId());

        MchBO mchBO = this.schedulerFacade.getMch(request, sign.getMchId());
        editPayPaymentBO = this.wxService.syncWxPay(editPayPaymentBO, mchBO);

        if (editPayPaymentBO.getAmount().compareTo(dbPayPaymentBO.getAmount()) != 0){
            logger.error("支付金额错误："+ JSON.toJSONString(payPaymentBO));
            throw new MallException("支付金额错误");
        }
        this.payPaymentService.update(editPayPaymentBO);

        // 生成分账信息
        PayDivideBO payDivideBO = new PayDivideBO();
        payDivideBO.setMchId(dbPayPaymentBO.getMchId());
        payDivideBO.setMemberId(dbPayPaymentBO.getMemberId());
        payDivideBO.setBizId(dbPayPaymentBO.getOrdersId());
        payDivideBO.setBizType(PayDivideTypeEnum.PLACE_ORDER.getType());
        payDivideBO.setPayPaymentId(dbPayPaymentBO.getId());
        payDivideBO.setPayAmount(dbPayPaymentBO.getAmount());
        payDivideBO.setStatus(PayDivideStatusEnum.DIVIDE_SUCCESS.getStatus());
        payDivideBO.setRemark("订单微信支付分账");
        MchBO dbMch = this.schedulerFacade.getMch(request, sign.getMchId());
        if (Objects.isNull(dbMch) || Objects.isNull(dbMch.getId())) {
            throw new MallException("分账时商户异常!");
        }
        BigDecimal divideAmount = dbPayPaymentBO.getAmount().multiply(dbMch.getDivideRatio());
        payDivideBO.setDivideAmount(divideAmount);
        super.setCreatedData(sign, payDivideBO);
        this.payDivideService.post(payDivideBO);

        // 修改订单信息
        OrdersBO editOrdersBO = new OrdersBO();
        editOrdersBO.setId(dbPayPaymentBO.getOrdersId());
        editOrdersBO.setPaymentId(dbPayPaymentBO.getId());
        editOrdersBO.setPayType(PayTypeEnum.WX_PAY.getType());

        editOrdersBO.setSuperiorAmount(payDivideBO.getDivideAmount());
        BigDecimal profitAmount = payDivideBO.getPayAmount().subtract(payDivideBO.getDivideAmount());
        editOrdersBO.setProfitAmount(profitAmount);
        editOrdersBO.setStatus(OrdersStatusEnum.SUCCESS.getStatus());

        CmdSign ordersPatchCmd = CmdSign.Builder.newBuild(sign)
                .setSource(editOrdersBO)
                .setCmdCode(OrdersCmdCode.ORDERS_PATCH)
                .setReqCode(ReqCode.PAY_SYNC_ORDERS)
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        this.scheduler.schedule(request,ordersPatchCmd);

        return respSign;
    }

    @Override
    public CmdSign verify(HttpServletRequest request, CmdSign sign) throws Exception {
        PayPaymentBO payPaymentBO = super.getData(sign, PayPaymentBO.class);
        if (payPaymentBO.getId() == null) {
            throw new MallException("支付id不能为空!");
        }
        return null;
    }


    @Override
    public String getCmdCode() {
        return PayPaymentCmdCode.PAY_PAYMENT_SYNC;
    }

    @Autowired
    private IPayPaymentService payPaymentService;
    @Autowired
    private IPayDivideService payDivideService;
    @Autowired
    private WxService wxService;
    @Autowired
    private MessageSender messageSender;
}
